package web.bfsdw;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.HttpRequest;
import web.servlet.BfsdwRequest;
import web.servlet.BfsdwResponse;
import web.servlet.BfsdwServlet;

import java.util.Map;

public class BfsdwWebHandler extends ChannelInboundHandlerAdapter {
    private Map<String, BfsdwServlet> nameToServletMap;
    private Map<String, String> nameToClassNameMap;
    public BfsdwWebHandler(Map<String, BfsdwServlet> nameToServletMap,
                           Map<String, String> nameToClassNameMap) {
        this.nameToServletMap = nameToServletMap;
        this.nameToClassNameMap = nameToClassNameMap;
    }
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof HttpRequest) {
            HttpRequest request = (HttpRequest) msg;
            // 从请求中解析出要访问的Servlet名称
            String uri = request.uri();

            //aaa/bbb/twoservlet?name=aa
            String servletName = uri.substring(uri.lastIndexOf("/") + 1,
                    uri.indexOf("?"));
            BfsdwServlet BfsdwServlet = new DefaultBfsdwServlet();
            if (nameToServletMap.containsKey(servletName)) { //后面每次都走
                BfsdwServlet = nameToServletMap.get(servletName);
            } else if (nameToClassNameMap.containsKey(servletName)) {
                // double-check，双重检测锁
                if (nameToServletMap.get(servletName) == null) {
                    synchronized (this) {
                        if (nameToServletMap.get(servletName) == null) {
                            // 获取当前Servlet的全限定性类名
                            String className =
                                    nameToClassNameMap.get(servletName);
                            // 使用反射机制创建Servlet实例
                            BfsdwServlet = (BfsdwServlet) Class.forName(className).newInstance();
                            // 将Servlet实例写入到nameToServletMap
                            nameToServletMap.put(servletName, BfsdwServlet);
                        }
                    }
                }
            } // end-else if
            // 代码走到这里，servlet肯定不空
            BfsdwRequest req = new HttpBfsdwRequest(request);
            BfsdwResponse res = new HttpBfsdwResponse(request, ctx);
            // 根据不同的请求类型，调用BfsdwServlet实例的不同方法
            if (request.method().name().equalsIgnoreCase("GET")) {
                BfsdwServlet.doGet(req, res);
            } else if(request.method().name().equalsIgnoreCase("POST")) {
                BfsdwServlet.doPost(req, res);
            }
            ctx.close();
        }
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}
